home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / scube.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  18.2 KB  |  735 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * 1992 David G Yu -- Silicon Graphics Computer Systems
  19.  */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <math.h>
  24. #include <X11/Xlib.h>
  25. #include <X11/keysym.h>
  26. #include <GL/glx.h>
  27. #include <GL/gl.h>
  28.  
  29. static int useRGB = 1;
  30. static int useLighting = 1;
  31. static int useFog = 0;
  32. static int useDB = 1;
  33. static int useLogo = 0;
  34. static int useQuads = 1;
  35.  
  36. #define GREY    0
  37. #define RED    1
  38. #define GREEN    2
  39. #define BLUE    3
  40. #define CYAN    4
  41. #define MAGENTA    5
  42. #define YELLOW    6
  43. #define BLACK    7
  44.  
  45. static float materialColor[8][4] = {
  46.     { 0.8, 0.8, 0.8, 1.0 },
  47.     { 0.8, 0.0, 0.0, 1.0 },
  48.     { 0.0, 0.8, 0.0, 1.0 },
  49.     { 0.0, 0.0, 0.8, 1.0 },
  50.     { 0.0, 0.8, 0.8, 1.0 },
  51.     { 0.8, 0.0, 0.8, 1.0 },
  52.     { 0.8, 0.8, 0.0, 1.0 },
  53.     { 0.0, 0.0, 0.0, 0.4 },
  54. };
  55.  
  56. static float lightPos[4] = { 2.0, 4.0, 2.0, 1.0 };
  57. static float lightDir[4] = { -2.0, -4.0, -2.0, 1.0 };
  58. static float lightAmb[4] = { 0.2, 0.2, 0.2, 1.0 };
  59. static float lightDiff[4] = { 0.8, 0.8, 0.8, 1.0 };
  60. static float lightSpec[4] = { 0.4, 0.4, 0.4, 1.0 };
  61.  
  62. static float groundPlane[4] = { 0.0, 1.0, 0.0, 1.499 };
  63. static float backPlane[4] = { 0.0, 0.0, 1.0, 0.899 };
  64.  
  65. static float fogColor[4] = { 0.0, 0.0, 0.0, 0.0 };
  66. static float fogIndex[1] = { 0.0 };
  67.  
  68. static unsigned char shadowPattern[128] = {
  69.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,    /* 50% Grey */
  70.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  71.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  72.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  73.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  74.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  75.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  76.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  77.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  78.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  79.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  80.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  81.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  82.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  83.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  84.     0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
  85. };
  86.  
  87. static unsigned char sgiPattern[128] = {
  88.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,     /* SGI Logo */
  89.     0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef, 
  90.     0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef, 
  91.     0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef, 
  92.     0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83, 
  93.     0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff, 
  94.     0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb, 
  95.     0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3, 
  96.     0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf, 
  97.     0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7, 
  98.     0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff, 
  99.     0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb, 
  100.     0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb, 
  101.     0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf, 
  102.     0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3, 
  103.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 
  104. };
  105.  
  106. static float cube_vertexes[6][4][4] = {
  107.     { { -1.0, -1.0, -1.0,  1.0 },
  108.       { -1.0, -1.0,  1.0,  1.0 },
  109.       { -1.0,  1.0,  1.0,  1.0 },
  110.       { -1.0,  1.0, -1.0,  1.0 } },
  111.  
  112.     { {  1.0,  1.0,  1.0,  1.0 },
  113.       {  1.0, -1.0,  1.0,  1.0 },
  114.       {  1.0, -1.0, -1.0,  1.0 },
  115.       {  1.0,  1.0, -1.0,  1.0 } },
  116.  
  117.     { { -1.0, -1.0, -1.0,  1.0 },
  118.       {  1.0, -1.0, -1.0,  1.0 },
  119.       {  1.0, -1.0,  1.0,  1.0 },
  120.       { -1.0, -1.0,  1.0,  1.0 } },
  121.  
  122.     { {  1.0,  1.0,  1.0,  1.0 },
  123.       {  1.0,  1.0, -1.0,  1.0 },
  124.       { -1.0,  1.0, -1.0,  1.0 },
  125.       { -1.0,  1.0,  1.0,  1.0 } },
  126.  
  127.     { { -1.0, -1.0, -1.0,  1.0 },
  128.       { -1.0,  1.0, -1.0,  1.0 },
  129.       {  1.0,  1.0, -1.0,  1.0 },
  130.       {  1.0, -1.0, -1.0,  1.0 } },
  131.  
  132.     { {  1.0,  1.0,  1.0,  1.0 },
  133.       { -1.0,  1.0,  1.0,  1.0 },
  134.       { -1.0, -1.0,  1.0,  1.0 },
  135.       {  1.0, -1.0,  1.0,  1.0 } }
  136. };
  137.  
  138. static float cube_normals[6][4] = {
  139.     { -1.0,  0.0,  0.0,  0.0 },
  140.     {  1.0,  0.0,  0.0,  0.0 },
  141.     {  0.0, -1.0,  0.0,  0.0 },
  142.     {  0.0,  1.0,  0.0,  0.0 },
  143.     {  0.0,  0.0, -1.0,  0.0 },
  144.     {  0.0,  0.0,  1.0,  0.0 }
  145. };
  146.  
  147. static void
  148. usage(int argc, char **argv)
  149. {
  150.     printf("\n");
  151.     printf("usage: %s [options]\n", argv[0]);
  152.     printf("\n");
  153.     printf("    display a spinning cube and its shadow\n");
  154.     printf("\n");
  155.     printf("  Options:\n");
  156.     printf("    -geometry  window size and location\n");
  157.     printf("    -c         toggle color index mode\n");
  158.     printf("    -l         toggle lighting\n");
  159.     printf("    -f         toggle fog\n");
  160.     printf("    -db        toggle double buffering\n");
  161.     printf("    -logo      toggle sgi logo for the shadow pattern\n");
  162.     printf("    -quads     toggle use of GL_QUADS to draw the checkerboard\n");
  163.     printf("\n");
  164.     exit(EXIT_FAILURE);
  165. }
  166.  
  167. static Colormap
  168. buildColormap(Display *dpy, Window root, XVisualInfo *vis)
  169. {
  170.     Colormap cmap;
  171.  
  172.     if (useRGB) {
  173.     cmap = XCreateColormap(dpy, root, vis->visual, AllocNone);
  174.     } else {
  175.     int  mapSize = 1 << vis->depth;
  176.     int  rampSize = mapSize / 8;
  177.     int  entry;
  178.     int i;
  179.  
  180.     cmap = XCreateColormap(dpy, root, vis->visual, AllocAll);
  181.  
  182.     for (entry = 0; entry < mapSize; ++entry)
  183.     {
  184.         XColor  col;
  185.         int     hue = entry / rampSize;
  186.         short   val = (entry % rampSize) * (0xffff / (rampSize-1));
  187.  
  188.         col.pixel = entry;
  189.         col.red   = (hue==0 || hue==1 || hue==5 || hue==6) ? val : 0;
  190.         col.green = (hue==0 || hue==2 || hue==4 || hue==6) ? val : 0;
  191.         col.blue  = (hue==0 || hue==3 || hue==4 || hue==5) ? val : 0;
  192.         col.flags = DoRed | DoGreen | DoBlue;
  193.  
  194.         XStoreColor(dpy, cmap, &col);
  195.     }
  196.  
  197.     for (i = 0; i < 8; ++i)
  198.     {
  199.         materialColor[i][0] = i*rampSize + 0.2 * (rampSize-1);
  200.         materialColor[i][1] = i*rampSize + 0.8 * (rampSize-1);
  201.         materialColor[i][2] = i*rampSize + 1.0 * (rampSize-1);
  202.         materialColor[i][3] = 0.0;
  203.     }
  204.  
  205.     fogIndex[0] = -0.2 * (rampSize-1);
  206.     }
  207.  
  208.     return cmap;
  209. }
  210.     
  211. static void
  212. setColor(int c)
  213. {
  214.     if (useLighting) {
  215.     if (useRGB) {
  216.         glMaterialfv(GL_FRONT_AND_BACK,
  217.              GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
  218.     } else {
  219.         glMaterialfv(GL_FRONT_AND_BACK,
  220.              GL_COLOR_INDEXES, &materialColor[c][0]);
  221.     }
  222.     } else {
  223.     if (useRGB) {
  224.         glColor4fv(&materialColor[c][0]);
  225.     } else {
  226.         glIndexf(materialColor[c][1]);
  227.     }
  228.     }
  229. }
  230.  
  231. static void
  232. drawCube(int color)
  233. {
  234.     int i;
  235.  
  236.     setColor(color);
  237.  
  238.     for (i = 0; i < 6; ++i)
  239.     {
  240.     glNormal3fv(&cube_normals[i][0]);
  241.     glBegin(GL_POLYGON);
  242.         glVertex4fv(&cube_vertexes[i][0][0]);
  243.         glVertex4fv(&cube_vertexes[i][1][0]);
  244.         glVertex4fv(&cube_vertexes[i][2][0]);
  245.         glVertex4fv(&cube_vertexes[i][3][0]);
  246.     glEnd();
  247.     }
  248. }
  249.  
  250. static void
  251. drawCheck(int w, int h, int evenColor, int oddColor)
  252. {
  253.     static int     initialized = 0;
  254.     static int     usedLighting = 0;
  255.     static GLuint  checklist = 0;
  256.  
  257.     if (!initialized || (usedLighting != useLighting))
  258.     {
  259.     static float   square_normal[4] = { 0.0, 0.0, 1.0, 0.0 };
  260.     static float   square[4][4];
  261.     int    i, j;
  262.  
  263.     if (!checklist)
  264.     {
  265.         checklist = glGenLists(1);
  266.     }
  267.     glNewList(checklist, GL_COMPILE_AND_EXECUTE);
  268.  
  269.     if (useQuads) {
  270.         glNormal3fv(square_normal);
  271.         glBegin(GL_QUADS);
  272.     }
  273.  
  274.     for (j = 0; j < h; ++j)
  275.     {
  276.         for (i = 0; i < w; ++i)
  277.         {
  278.         square[0][0] = -1.0 + 2.0/w * i;
  279.         square[0][1] = -1.0 + 2.0/h * (j+1);
  280.         square[0][2] = 0.0;
  281.         square[0][3] = 1.0;
  282.  
  283.         square[1][0] = -1.0 + 2.0/w * i;
  284.         square[1][1] = -1.0 + 2.0/h * j;
  285.         square[1][2] = 0.0;
  286.         square[1][3] = 1.0;
  287.  
  288.         square[2][0] = -1.0 + 2.0/w * (i+1);
  289.         square[2][1] = -1.0 + 2.0/h * j;
  290.         square[2][2] = 0.0;
  291.         square[2][3] = 1.0;
  292.  
  293.         square[3][0] = -1.0 + 2.0/w * (i+1);
  294.         square[3][1] = -1.0 + 2.0/h * (j+1);
  295.         square[3][2] = 0.0;
  296.         square[3][3] = 1.0;
  297.  
  298.         if (i & 1 ^ j & 1) {
  299.             setColor(oddColor);
  300.         } else {
  301.             setColor(evenColor);
  302.         }
  303.  
  304.         if (!useQuads) {
  305.             glBegin(GL_POLYGON);
  306.         }
  307.         glVertex4fv(&square[0][0]);
  308.         glVertex4fv(&square[1][0]);
  309.         glVertex4fv(&square[2][0]);
  310.         glVertex4fv(&square[3][0]);
  311.         if (!useQuads) {
  312.             glEnd();
  313.         }
  314.         }
  315.     }
  316.  
  317.     if (useQuads) {
  318.         glEnd();
  319.     }
  320.  
  321.     glEndList();
  322.  
  323.     initialized = 1;
  324.     usedLighting = useLighting;
  325.     }
  326.     else
  327.     {
  328.     glCallList(checklist);
  329.     }
  330. }
  331.  
  332. static void
  333. myShadowMatrix(float ground[4], float light[4])
  334. {
  335.     float  dot;
  336.     float  shadowMat[4][4];
  337.  
  338.     dot = ground[0] * light[0] +
  339.           ground[1] * light[1] +
  340.           ground[2] * light[2] +
  341.           ground[3] * light[3];
  342.     
  343.     shadowMat[0][0] = dot - light[0] * ground[0];
  344.     shadowMat[1][0] = 0.0 - light[0] * ground[1];
  345.     shadowMat[2][0] = 0.0 - light[0] * ground[2];
  346.     shadowMat[3][0] = 0.0 - light[0] * ground[3];
  347.     
  348.     shadowMat[0][1] = 0.0 - light[1] * ground[0];
  349.     shadowMat[1][1] = dot - light[1] * ground[1];
  350.     shadowMat[2][1] = 0.0 - light[1] * ground[2];
  351.     shadowMat[3][1] = 0.0 - light[1] * ground[3];
  352.     
  353.     shadowMat[0][2] = 0.0 - light[2] * ground[0];
  354.     shadowMat[1][2] = 0.0 - light[2] * ground[1];
  355.     shadowMat[2][2] = dot - light[2] * ground[2];
  356.     shadowMat[3][2] = 0.0 - light[2] * ground[3];
  357.     
  358.     shadowMat[0][3] = 0.0 - light[3] * ground[0];
  359.     shadowMat[1][3] = 0.0 - light[3] * ground[1];
  360.     shadowMat[2][3] = 0.0 - light[3] * ground[2];
  361.     shadowMat[3][3] = dot - light[3] * ground[3];
  362.  
  363.     glMultMatrixf((const GLfloat*)shadowMat);
  364. }
  365.  
  366. static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)";
  367. static int visattrsRGBDB[] = {
  368.     GLX_RGBA,
  369.     GLX_DOUBLEBUFFER,
  370.     GLX_RED_SIZE, 1,
  371.     GLX_GREEN_SIZE, 1,
  372.     GLX_BLUE_SIZE, 1,
  373.     GLX_DEPTH_SIZE, 1,
  374.     None
  375. };
  376.  
  377. static char *windowNameRGB = "shadow cube (OpenGL RGB)";
  378. static int visattrsRGB[] = {
  379.     GLX_RGBA,
  380.     GLX_RED_SIZE, 1,
  381.     GLX_GREEN_SIZE, 1,
  382.     GLX_BLUE_SIZE, 1,
  383.     GLX_DEPTH_SIZE, 1,
  384.     None
  385. };
  386.  
  387. static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)";
  388. static int visattrsIndexDB[] = {
  389.     GLX_DOUBLEBUFFER,
  390.     GLX_BUFFER_SIZE, 4,
  391.     GLX_DEPTH_SIZE, 1,
  392.     None
  393. };
  394.  
  395. static char *windowNameIndex = "shadow cube (OpenGL Index)";
  396. static int visattrsIndex[] = {
  397.     GLX_BUFFER_SIZE, 8,
  398.     GLX_DEPTH_SIZE, 1,
  399.     None
  400. };
  401.  
  402. static Bool
  403. waitForNotify(Display *dpy, XEvent *event, char *arg)
  404. {
  405.     return (event->type == MapNotify) && (event->xmap.window == (Window)arg);
  406. }
  407.  
  408. int
  409. main(int argc, char **argv)
  410. {
  411.     Display               *dpy;
  412.     char                  *geometry = NULL;
  413.     int                   scr;
  414.     int                   *visattrs;
  415.     XVisualInfo           *vis;
  416.     XSetWindowAttributes  swa;
  417.     int                   width = 300, height = 300;
  418.     Window                win;
  419.     GLXContext            ctx;
  420.     char                  *name;
  421.     XSizeHints            sizehints;
  422.     XEvent                event;
  423.     int                   i;
  424.  
  425.     GLfloat               cubeXform[4][4];
  426.  
  427.     /* process commmand line args */
  428.     for (i = 1; i < argc; ++i)
  429.     {
  430.     if (!strcmp("-geometry", argv[i]))
  431.     {
  432.        i++;
  433.        geometry = argv[i];
  434.        if (geometry == NULL) {
  435.            usage(argc, argv);
  436.        }
  437.     }
  438.     else if (!strcmp("-c", argv[i]))
  439.     {
  440.         useRGB = !useRGB;
  441.     }
  442.     else if (!strcmp("-l", argv[i]))
  443.     {
  444.         useLighting = !useLighting;
  445.     }
  446.     else if (!strcmp("-f", argv[i]))
  447.     {
  448.         useFog = !useFog;
  449.     }
  450.     else if (!strcmp("-db", argv[i]))
  451.     {
  452.         useDB = !useDB;
  453.     }
  454.     else if (!strcmp("-logo", argv[i]))
  455.     {
  456.         useLogo = !useLogo;
  457.     }
  458.     else if (!strcmp("-quads", argv[i]))
  459.     {
  460.         useQuads = !useQuads;
  461.     }
  462.     else
  463.     {
  464.         usage(argc, argv);
  465.     }
  466.     }
  467.  
  468.     /* open connection */
  469.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  470.     fprintf(stderr, "couldn't open display\n");
  471.     exit(EXIT_FAILURE);
  472.     }
  473.     scr = DefaultScreen(dpy);
  474.  
  475.     /* choose visual */
  476.     if (useRGB) {
  477.     if (useDB) {
  478.         visattrs = visattrsRGBDB;
  479.         name = windowNameRGBDB;
  480.     } else {
  481.         visattrs = visattrsRGB;
  482.         name = windowNameRGB;
  483.     }
  484.     } else {
  485.     if (useDB) {
  486.         visattrs = visattrsIndexDB;
  487.         name = windowNameIndexDB;
  488.     } else {
  489.         visattrs = visattrsIndex;
  490.         name = windowNameIndex;
  491.     }
  492.     }
  493.  
  494.     if ((vis = glXChooseVisual(dpy, scr, visattrs)) == NULL) {
  495.     fprintf(stderr, "couldn't find visual\n");
  496.     exit(EXIT_FAILURE);
  497.     }
  498.  
  499.     /* create context */
  500.     if ((ctx = glXCreateContext(dpy, vis, None, True)) == NULL) {
  501.     fprintf(stderr, "couldn't create context\n");
  502.     exit(EXIT_FAILURE);
  503.     }
  504.  
  505.     /* create window */
  506.     sizehints.flags = PPosition | PSize;
  507.     sizehints.width = width;
  508.     sizehints.height = height;
  509.     sizehints.x = 0;
  510.     sizehints.y = 0;
  511.     if(geometry) {
  512.         int flags, x, y, width, height;
  513.  
  514.         flags = XParseGeometry(geometry, &x, &y,
  515.                                (unsigned int *)&width,
  516.                                (unsigned int *)&height);
  517.         if(WidthValue & flags) {
  518.         sizehints.flags |= USSize;
  519.         sizehints.width = width;
  520.         }
  521.         if(HeightValue & flags) {
  522.         sizehints.flags |= USSize;
  523.         sizehints.height = height;
  524.         }
  525.         if(XValue & flags) {
  526.         if(XNegative & flags)
  527.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  528.             - sizehints.width;
  529.             sizehints.flags |= USPosition;
  530.         sizehints.x = x;
  531.         }
  532.         if(YValue & flags) {
  533.         if(YNegative & flags)
  534.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
  535.             - sizehints.height;
  536.             sizehints.flags |= USPosition;
  537.         sizehints.y = y;
  538.         }
  539.     }
  540.     swa.colormap = buildColormap(dpy, RootWindow(dpy, scr), vis);
  541.     swa.border_pixel = 0;
  542.     swa.background_pixel = 0;
  543.     swa.event_mask = KeyPressMask | StructureNotifyMask;
  544.     win = XCreateWindow(dpy, RootWindow(dpy, scr),
  545.             sizehints.x, sizehints.y,
  546.             sizehints.width, sizehints.height,
  547.             0, vis->depth, InputOutput, vis->visual,
  548.             CWBorderPixel | CWBackPixel | CWColormap | CWEventMask,
  549.             &swa);
  550.     
  551.     XSetStandardProperties(dpy, win, name, name, None,
  552.                argv, argc, &sizehints);
  553.  
  554.     XMapWindow(dpy, win);
  555.     XIfEvent(dpy, &event, waitForNotify, (char*)win);
  556.  
  557.     /* bind context to window */
  558.     glXMakeCurrent(dpy, win, ctx);
  559.  
  560.     /* setup context */
  561.     glMatrixMode(GL_PROJECTION);
  562.     glLoadIdentity();
  563.     glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
  564.  
  565.     glMatrixMode(GL_MODELVIEW);
  566.     glLoadIdentity();
  567.     glTranslatef(0.0, 0.0, -2.0);
  568.  
  569.     glEnable(GL_DEPTH_TEST);
  570.  
  571.     if (useLighting) {
  572.     glEnable(GL_LIGHTING);
  573.     }
  574.     glEnable(GL_LIGHT0);
  575.     glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  576.     glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  577.     glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  578.     glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  579.     /*
  580.     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
  581.     glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
  582.     glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
  583.     */
  584.  
  585.     glEnable(GL_NORMALIZE);
  586.  
  587.     if (useFog) {
  588.     glEnable(GL_FOG);
  589.     }
  590.     glFogfv(GL_FOG_COLOR, fogColor);
  591.     glFogfv(GL_FOG_INDEX, fogIndex);
  592.     glFogf(GL_FOG_MODE, GL_EXP);
  593.     glFogf(GL_FOG_DENSITY, 0.5);
  594.     glFogf(GL_FOG_START, 1.0);
  595.     glFogf(GL_FOG_END, 3.0);
  596.  
  597.     glEnable(GL_CULL_FACE);
  598.     glCullFace(GL_BACK);
  599.  
  600.     glShadeModel(GL_SMOOTH);
  601.  
  602.     glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
  603.     if (useLogo) {
  604.     glPolygonStipple((const GLubyte *)sgiPattern);
  605.     } else {
  606.     glPolygonStipple((const GLubyte *)shadowPattern);
  607.     }
  608.  
  609.     glClearColor(0.0, 0.0, 0.0, 1);
  610.     glClearIndex(0);
  611.     glClearDepth(1);
  612.  
  613.     /* spin cube */
  614.     while (1)
  615.     {
  616.     for (i = 0; i < 120; ++i)
  617.     {
  618.         if (XPending(dpy)) {
  619.         XNextEvent(dpy, &event);
  620.  
  621.         switch (event.type) {
  622.           case KeyPress:
  623.             {
  624.             KeySym ks;
  625.             char buf[2];
  626.  
  627.             XLookupString(&event.xkey, buf, 2, &ks, NULL);
  628.             switch (ks) {
  629.               case XK_Escape:
  630.                 exit(0);
  631.                 break;
  632.               case XK_L: case XK_l:
  633.                 useLighting = !useLighting;
  634.                 useLighting ? glEnable(GL_LIGHTING) :
  635.                       glDisable(GL_LIGHTING);
  636.                 break;
  637.               case XK_F: case XK_f:
  638.                 useFog = !useFog;
  639.                 useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  640.                 break;
  641.               case XK_1:
  642.                 glFogf(GL_FOG_MODE, GL_LINEAR);
  643.                 break;
  644.               case XK_2:
  645.                 glFogf(GL_FOG_MODE, GL_EXP);
  646.                 break;
  647.               case XK_3:
  648.                 glFogf(GL_FOG_MODE, GL_EXP2);
  649.                 break;
  650.               default:
  651.                 break;
  652.             }
  653.             }
  654.             break;
  655.           case ConfigureNotify:
  656.             width = event.xconfigure.width;
  657.             height = event.xconfigure.height;
  658.             glViewport(0, 0, width, height);
  659.             break;
  660.           default:
  661.             break;
  662.         }
  663.         }
  664.  
  665.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  666.  
  667.         glPushMatrix();
  668.         glTranslatef(0.0, -1.5, 0.0);
  669.         glRotatef(-90.0, 1, 0, 0);
  670.         glScalef(2.0, 2.0, 2.0);
  671.  
  672.         drawCheck(6, 6, BLUE, YELLOW);        /* draw ground */
  673.         glPopMatrix();
  674.  
  675.         glPushMatrix();
  676.         glTranslatef(0.0, 0.0, -0.9);
  677.         glScalef(2.0, 2.0, 2.0);
  678.  
  679.         drawCheck(6, 6, BLUE, YELLOW);        /* draw back */
  680.         glPopMatrix();
  681.  
  682.         glPushMatrix();
  683.         glTranslatef(0.0, 0.2, 0.0);
  684.         glScalef(0.3, 0.3, 0.3);
  685.         glRotatef((360.0 / (30 * 1)) * i, 1, 0, 0);
  686.         glRotatef((360.0 / (30 * 2)) * i, 0, 1, 0);
  687.         glRotatef((360.0 / (30 * 4)) * i, 0, 0, 1);
  688.         glScalef(1.0, 2.0, 1.0);
  689.         glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)cubeXform);
  690.  
  691.         drawCube(RED);                /* draw cube */
  692.         glPopMatrix();
  693.  
  694.         glDepthMask(GL_FALSE);
  695.         if (useRGB) {
  696.         glEnable(GL_BLEND);
  697.         } else {
  698.         glEnable(GL_POLYGON_STIPPLE);
  699.         }
  700.         if (useFog) {
  701.         glDisable(GL_FOG);
  702.         }
  703.  
  704.         glPushMatrix();
  705.         myShadowMatrix(groundPlane, lightPos);
  706.         glTranslatef(0.0, 0.0, 2.0);
  707.         glMultMatrixf((const GLfloat *) cubeXform);
  708.  
  709.         drawCube(BLACK);                /* draw ground shadow */
  710.         glPopMatrix();
  711.  
  712.         glPushMatrix();
  713.         myShadowMatrix(backPlane, lightPos);
  714.         glTranslatef(0.0, 0.0, 2.0);
  715.         glMultMatrixf((const GLfloat *) cubeXform);
  716.  
  717.         drawCube(BLACK);                /* draw back shadow */
  718.         glPopMatrix();
  719.  
  720.         glDepthMask(GL_TRUE);
  721.         if (useRGB) {
  722.         glDisable(GL_BLEND);
  723.         } else {
  724.         glDisable(GL_POLYGON_STIPPLE);
  725.         }
  726.         if (useFog) {
  727.         glEnable(GL_FOG);
  728.         }
  729.  
  730.         glXSwapBuffers(dpy, win);
  731.     }
  732.     }
  733. }
  734.  
  735.